﻿using Daemon.Model;
using Microsoft.AspNetCore.Mvc;
using Daemon.Common;
using Daemon.Repository.Contract;
using System.Net.Http;
using Microsoft.AspNetCore.Http;
using ThoughtWorks.QRCode;
using ThoughtWorks.QRCode.Codec;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Collections.Generic;
using Microsoft.Extensions.Configuration;
using System.Text;
using Daemon.Model.ViewModel;
using Daemon.Common.Exceptions;
using Daemon.Data.Substructure.Enums;
using Newtonsoft.Json;
using System.Threading.Tasks;
using Daemon.Common.WxPay;

namespace DaemonAPI.Controllers.V1.TakeAway
{
    [ApiController]
    [Route("api/[controller]/[action]")]
    public class WxPayController : BaseApiController
    {
        private readonly IClientConfigRepository _clientConfigRepository;

        private readonly ITakeAwayUserOrderRepository _takeAwayUserOrderRepository;

        private readonly IHttpClientFactory _httpClientFactory;

        private readonly ITakeAwayUserRepository _takeAwayUserRepository;

        public WxPayController(IClientConfigRepository clientConfigRepository,
        ITakeAwayUserOrderRepository takeAwayUserOrderRepository,
        ITakeAwayUserRepository takeAwayUserRepository,
        IHttpClientFactory httpClientFactory)
        {
            _clientConfigRepository = clientConfigRepository;
            _takeAwayUserOrderRepository = takeAwayUserOrderRepository;
            _takeAwayUserRepository = takeAwayUserRepository;
            _httpClientFactory = httpClientFactory;
        }

        [Route("")]
        [HttpGet]
        public ResultModel<bool> NotifyOrder(int orderId)
        {
            return new ResultModel<bool>(HttpStatusCode.OK, true);
        }

        [Route("")]
        [HttpPost]
        public async Task<ResultModel<WxPayRequestModel>> Pay(int orderId)
        {
            var clientConfig = _clientConfigRepository.Find();
            var currentOrder = _takeAwayUserOrderRepository.FindById(orderId);
            if (currentOrder == null)
            {
                throw new BusinessException((int)BusinessCode.NonExist, "");
            }

            var currentUser = _takeAwayUserRepository.FindById(currentOrder.UserId);
            var url = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";
            var req = new GenerateOrderModelForWxPay
            {
                appid = clientConfig.AppId,
                mchid = clientConfig.MchId,
                description = "鱼米演绎外卖",
                amount = new WxPayAmountModel
                {
                    total = Convert.ToInt32(currentOrder.Price * 100),
                    currency = "CNY"
                },
                payer = new WxPayerModel
                {
                    openid = currentUser.OpenId
                },
                out_trade_no = currentOrder.OrderNumber,
                notify_url = clientConfig.NotifyUrl
            };
            var client = _httpClientFactory.CreateClient();
            var timeStamp = WxPayHelper.getTimeStamp();
            var bodyJson = new StringContent(JsonConvert.SerializeObject(req), Encoding.UTF8, "application/json");
            var signature = WxPayHelper.getAuthorization("POST", "/v3/pay/transactions/jsapi", JsonConvert.SerializeObject(req), clientConfig.MchId, clientConfig.SerialNo, WxPayHelper.GenerateRandomString(32), timeStamp);
            client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", $"WECHATPAY2-SHA256-RSA2048 {signature}");
            client.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "application/json");
            client.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", " Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, likeGecko)Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586");
            client.BaseAddress = new Uri(url);
            var response = await client.PostAsync(url, bodyJson);
            var content = await response.Content.ReadAsStringAsync();
            var package = "prepay_id=" + JsonConvert.DeserializeObject<PrePay>(content).prepay_id;
            var nonceStr = WxPayHelper.GenerateRandomString(32);
            var wxRequestPayModel = new WxPayRequestModel() { orderInfo = currentOrder, timeStamp = timeStamp.ToString(), nonceStr = nonceStr, package = package, signType = "sha256", paySign = WxPayHelper.getSignature(clientConfig.AppId, timeStamp, nonceStr, package, "sha256") };
            return new ResultModel<WxPayRequestModel>(HttpStatusCode.OK, wxRequestPayModel, "");
        }

        private async Task<string> Signature(long timeStamp, string nonceStr)
        {
            var clientConfig = _clientConfigRepository.Find();
            var authorization = WxPayHelper.getAuthorization("GET", "/v3/certificates", "", clientConfig.MchId, clientConfig.SerialNo, nonceStr, timeStamp);
            var client = _httpClientFactory.CreateClient();
            client.BaseAddress = new Uri("https://api.mch.weixin.qq.com/v3/certificates");
            client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", $"WECHATPAY2-SHA256-RSA2048 {authorization}");
            client.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "text/html,application/xhtml+xml,image/jxr,*/*");
            client.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", " Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, likeGecko)Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586");
            var signResponse = await client.GetAsync("https://api.mch.weixin.qq.com/v3/certificates");
            var signature = await signResponse.Content.ReadAsStringAsync();
            return signature;
        }
    }
}
